/*
 * ECARX Technology Limited is the owner of the copyright and the trade secret of this software.
 * Without permission, no one has the right to obtain, disclose or use this software in any way.
 */

package com.ecarx.systemui.plugin.ui.dialog.base;

import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import androidx.annotation.NonNull;

import com.ecarx.systemui.plugin.AppConstants;
import com.ecarx.systemui.plugin.NavigationBar;
import com.ecarx.systemui.plugin.R;
import com.ecarx.systemui.plugin.model.listener.GestureCallback;
import com.ecarx.systemui.plugin.utils.DensityUtils;
import com.ecarx.systemui.plugin.utils.LogUtils;


public abstract class AutoCloseDialog extends Dialog {

    private static final String TAG = "AutoCloseDialogTag";

    private long DEFAULT_DIALOG_AUTO_DISMISS_TIME = 5000L;

    private TimerHandler mTimerHandler;

//    GestureCallback gestureCallback;
    protected Animation enterAnimation;
    protected Animation outAnimation;

    public AutoCloseDialog(@NonNull Context context) {
        this(context, 0);
    }

    public AutoCloseDialog(@NonNull Context context, int themeResId) {
        super(context, R.style.PluginDialog);
        enterAnimation = AnimationUtils.loadAnimation(context, R.anim.dock_dialog_enter_anim);
        outAnimation = AnimationUtils.loadAnimation(context, R.anim.dock_dialog_exit_anim);
//        gestureCallback = (GestureCallback) NavigationBar.init(context).getRootView();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    public void setDefaultDialogAutoDismissTime(long dismissTime) {
        this.DEFAULT_DIALOG_AUTO_DISMISS_TIME = dismissTime;
    }

    /**
     * 此方法用于延迟退出，可以执行退出动画
     */
    protected void delayedDismiss() {

    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
//        if (gestureCallback != null) {
//            gestureCallback.setDispatchTouchEventCall(ev -> {
//                if (ev.getAction() == ACTION_DOWN) {
//                    //不在此处处理
//                    //dismiss();
//                }
//            });
//        }
//        startDeployAutoEvent();
    }

    /**
     * 部署外部拦截事件,  因为不同window之间无法直接传递事件, WindowManagerGlobal内有不同window中的view, 找到其他window中的view
     * 设置onTouch, 来判断是否触摸在外部,  dialog自身布局需要拦截的区域xml布局中添加android:clickable="true" 来消费,
     * 这样其他区域都会执行到外部的onTouch里, 所以只要进了onTouch, 肯定在外部, 因为Window中是不包含状态栏和导航栏的, 所以需要另外使用
     * 接口的方式来实现 NavigationBarView和StatusBarView通过实现GestureCallback来回调dispatchTouchEvent事件
     */
    @SuppressLint("ClickableViewAccessibility")
    protected void startDeployAutoEvent() {
        String[] viewRootNames = WindowManagerGlobal.getInstance().getViewRootNames();
        for (String viewRootName : viewRootNames) {
            WindowManagerGlobal.getInstance().getRootView(viewRootName).setOnTouchListener((v, event) -> {
                stopDeployAutoEvent();
                LogUtils.i(TAG, "startDeployAutoEvent dismiss()");
                dismiss();
                return false;
            });
        }
    }

    /**
     * 清空回调, 减少不必要性能消耗
     */
    private void stopDeployAutoEvent() {
        String[] viewRootNames = WindowManagerGlobal.getInstance().getViewRootNames();
        for (String viewRootName : viewRootNames) {
            WindowManagerGlobal.getInstance().getRootView(viewRootName).setOnTouchListener(null);
        }
    }


    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
//        if (gestureCallback != null) {
//            gestureCallback.setDispatchTouchEventCall(null);
//        }
    }

    @Override
    public void show() {
        super.show();
        if (isAutoDismiss()) {
            startTimingClose();
        }
    }

    protected boolean isAutoDismiss(){
        return true;
    }

    @Override
    public void dismiss() {
        super.dismiss();
        cancelTimingClose();
    }

    @Override
    public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
        if(ev.getAction() == ACTION_DOWN || ev.getAction() == ACTION_UP || ev.getAction() == ACTION_CANCEL){
            //refresh timer
            startTimingClose();
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 取消倒计时
     */
    public void cancelTimingClose() {
        if (mTimerHandler != null) {
            mTimerHandler.cancel();
            mTimerHandler = null;
        }
    }

    /**
     * 开始自动关闭计时任务
     */
    public void startTimingClose() {
        if (!isAutoDismiss()) {
            return;
        }
        cancelTimingClose();
        mTimerHandler = TimerHandler.obtainTimerHandler();
        mTimerHandler.start(DEFAULT_DIALOG_AUTO_DISMISS_TIME, new TimerHandler.TimerCompleteListener() {
            @Override
            public void onComplete() {
                dismiss();
            }
        });
    }


    protected void initWindow(int posX){
        Window window = getWindow();
        if (window != null) {
            WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.MATCH_PARENT,
                    AppConstants.PLUGIN_DIALOG_TYPE,
                    android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN |
                            android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
                            android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                    ,
                    PixelFormat.TRANSPARENT);
            params.gravity = Gravity.START | Gravity.TOP;
            params.y = DensityUtils.dp2px(94);
            params.x = posX;
            LogUtils.d(TAG, "params.x= " + posX);
            window.setAttributes(params);
            setCanceledOnTouchOutside(true);
        }
    }
}
